package itsm.isperp.module.service.app;

import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.module.dto.app.FullCalendarDTO;
import itsm.isperp.module.entity.app.AppCalendarConfig;
import itsm.isperp.module.entity.app.AppCalendarWorkdate;
import itsm.isperp.module.repository.app.AppCalendarConfigMapper;
import itsm.isperp.module.repository.app.AppCalendarDayMapper;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

/**
 * 系统日历配置服务
 * 
 * @author lizx
 * @date 2013-5-12
 * @version V1.0
 */
@Service
public class AppCalendarConfigService extends BaseService<AppCalendarConfig> {

	@Autowired
	protected AppCalendarConfigMapper appCalendarConfigMapper;

	@Autowired
	protected AppCalendarDayMapper appCalendarDayMapper;

	@Autowired
	protected AppCalendarWorkdateService appCalendarWorkdateService;

	@Autowired
	protected JdbcTemplate jdbcTemplate;

	@Override
	public AppCalendarConfigMapper getRepository() {
		return this.appCalendarConfigMapper;
	}

	/**
	 * 根据启动时间及日历配置获取启动时间至当前时间的工作时间的秒数
	 * 
	 * @param startDatetime
	 * @param id
	 * @return
	 */
	public int elapsedWorktime(Date startDatetime, String id) {
		return this.getRepository().elapsedWorktime(startDatetime, id);
	}

	/**
	 * 根据指定的开始时间及消耗的工时秒数和工作日历id返回结束工作日时间
	 * 
	 * @param startDatetime
	 * @param elapsedSecond
	 * @param id
	 * @return
	 */
	public Date getWorktime(Date startDatetime, int elapsedSecond, String id) {

		return this.getRepository().getWorktime(startDatetime, elapsedSecond,
				id);
	}

	@Override
	public int saveOrUpdate(AppCalendarConfig entity, HttpServletRequest req) {
		super.saveOrUpdate(entity, req);
		appCalendarDayMapper.deleteByConfigId(entity.getId());
		// 根据配置重建日历
		Calendar fromC = Calendar.getInstance();
		fromC.setTime(entity.getFromDate());

		Calendar toC = Calendar.getInstance();
		toC.setTime(entity.getToDate());

		long intervalMilli = entity.getToDate().getTime()
				- entity.getFromDate().getTime();
		int days = (int) (intervalMilli / (24 * 60 * 60 * 1000));

		List<AppCalendarWorkdate> workdates = appCalendarWorkdateService
				.findByConfigId(entity.getId());
		Map<Date, AppCalendarWorkdate> workdateMap = new HashMap<>();
		for (AppCalendarWorkdate d : workdates) {
			workdateMap.put(d.getCalendarDate(), d);
		}

		List<Object[]> args = new ArrayList<>();

		for (int i = 0; i < days; i++) {
			fromC.add(Calendar.DAY_OF_MONTH, 1);
			Object[] arg = new Object[8];
			arg[0] = HibernateUUIDGenerator.generate();
			arg[1] = fromC.getTime();
			arg[2] = entity.getAmBegin();
			arg[3] = entity.getAmEnd();
			arg[4] = entity.getPmBegin();
			arg[5] = entity.getPmEnd();
			AppCalendarWorkdate d = workdateMap.get(arg[1]);

			if (d != null) {
				arg[6] = d.isDateType();
			} else {
				arg[6] = this.isNormalWorkdate(fromC.getTime(), true, entity);
			}
			arg[7] = entity.getId();

			args.add(arg);
		}
		String sql = "INSERT INTO app_calendar_day (id,calendar_date,am_begin,am_end,pm_begin,pm_end,STATUS,app_calendar_config_id)VALUES(?,?,?,?,?,?,?,?)";
		if (args.size() > 0) {
			this.jdbcTemplate.batchUpdate(sql, args);
		}
		return 1;

	}

	public List<FullCalendarDTO> getWorkday(Date startDate, Date endDate,
			String id) {

		return this.getRepository().findWorkday(startDate, endDate, id);
	}

	public void setWokdate(String workdate, boolean isWorkday, String configId)
			throws ParseException {
		// 首先判断workdate是否是日历中一个普通的工作日或者非工作日
		// 查询app_calendar_workdate是否存在此日期
		// 如果存在此日期，按照日期逻辑设定/删除记录（如果日期由非一般日期设为一般日期）
		// 更新app_calendar_day的数据为指定的status
		Date workdateDate = SimpleDateFormat.getDateInstance().parse(workdate);
		boolean normalWorkdate = this.isNormalWorkdate(workdateDate, isWorkday,
				this.appCalendarConfigMapper.findOne(configId));

		AppCalendarWorkdate appCalendarWorkdate = this.appCalendarWorkdateService
				.findOneByWorkdateAndConfig(workdateDate, configId);
		if (appCalendarWorkdate == null) {
			if (!normalWorkdate) {
				// 增加一条记录
				appCalendarWorkdate = new AppCalendarWorkdate();

				appCalendarWorkdate.setAppCalendarConfigId(configId);
				appCalendarWorkdate.setDateType(isWorkday);
				appCalendarWorkdate.setCalendarDate(workdateDate);

				this.appCalendarWorkdateService
						.saveOrUpdate(appCalendarWorkdate);
			}

		} else {
			if (normalWorkdate) {
				if (appCalendarWorkdate.isDateType() == isWorkday) {
					// 删除
					this.appCalendarWorkdateService.delete(appCalendarWorkdate
							.getId());
				}

			}

		}

		this.appCalendarDayMapper.updateStatus(isWorkday, workdateDate,
				configId);
	}

	private boolean isNormalWorkdate(Date workdate, boolean isWorkday,
			AppCalendarConfig config) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(workdate);
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		switch (dayOfWeek) {
		case Calendar.SUNDAY:
			return isWorkday == config.isWeek7();
		case Calendar.MONDAY:
			return isWorkday == config.isWeek1();
		case Calendar.TUESDAY:
			return isWorkday == config.isWeek2();
		case Calendar.WEDNESDAY:
			return isWorkday == config.isWeek3();
		case Calendar.THURSDAY:
			return isWorkday == config.isWeek4();
		case Calendar.FRIDAY:
			return isWorkday == config.isWeek5();
		case Calendar.SATURDAY:
			return isWorkday == config.isWeek6();
		}

		return false;
	}
}